﻿using System;
using System.Configuration;
using System.IO;
using System.Linq.Expressions;

namespace blackhouse.WebNemo.Business.Groups {
    public abstract class RecordFileOperation {

        #region Instance

        private static Func<int, string, int, RecordFileOperation> _initialize;

        public static RecordFileOperation Get(IGroupRecord record, string column) {
            return Get(record.BelongsToGroupId, column, record.RecordId);
        }

        public static RecordFileOperation Get(int groupId, string column, int recordId) {
            if (_initialize != null) return _initialize(groupId, column, recordId);

            var t = GetRecordFileOperationType();
            var ci = t.GetConstructor(new[] { typeof(Int32), typeof(String), typeof(Int32) });
            if (ci == null)
                throw new ConfigurationErrorsException("Nie znaleziono konstruktora (String, String, Int32)");
            var pGroupId = Expression.Parameter(typeof(Int32));
            var pColumn = Expression.Parameter(typeof(String));
            var pRecordId = Expression.Parameter(typeof(Int32));
            //ParameterExpression pRecordFileOperation = Expression.Parameter(typeof(RecordFileOperation));
            _initialize = Expression.Lambda<Func<int, string, int, RecordFileOperation>>(Expression.New(ci, pGroupId, pColumn, pRecordId), pGroupId, pColumn, pRecordId).Compile();
            //initialize = Expression.Lambda<Func<IGroupRecord, string, RecordFileOperation>>(Expression.New(ci, Expression.Parameter(typeof(IGroupRecord)), Expression.Parameter(typeof(string))),).Compile();
            return _initialize(groupId, column, recordId);
        }

        private static Type GetRecordFileOperationType() {
            var st = ConfigurationManager.AppSettings["RecordFileOperation"];
            var t = typeof(NemoRecordFileOperation);
            if (!String.IsNullOrEmpty(st))
                t = Type.GetType(st, false);
            return t;
        }

        #endregion

        #region Fields

        protected readonly int GroupId;
        protected readonly string Column;
        protected readonly int RecordId;

        #endregion

        #region Constructors

        protected RecordFileOperation(int groupId, string column, int recordId) {
            this.GroupId = groupId;
            this.Column = column;
            this.RecordId = recordId;
        }

        #endregion

        #region Methods

        public abstract bool SaveFile(RecordFileData fileData, Stream fileStream);

        public abstract RecordFileData GetInfo();

        public abstract byte[] GetFileData();

        #endregion

    }
}
